﻿<!doctype html>
<html lang="en" style="margin:0;padding:0;">
<head>
<title>房间布局</title>
<meta charset="utf-8">
<meta name="viewport"
	content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body style="padding:0;margin:0;">

	<script src="js/jquery-1.9.1.js"></script>
	<script src="js/three.min.js"></script>
	<script src="js/OrbitControls.js"></script>
	<script src="js/ThreeBSP.js"></script>
	<script src="js/Detector.js"></script>
	<script src="js/stats.js"></script>

	<script src="js/THREEx.KeyboardState.js"></script>
	<script src="js/THREEx.FullScreen.js"></script>
	<script src="js/THREEx.WindowResize.js"></script>

	<!-- people -->
	<script src="people/js/three.js"></script>
	<script src="people/js/DDSLoader.js"></script>
	<script src="people/js/MTLLoader.js"></script>
	<script src="people/js/OBJLoader.js"></script>
	<script src="people/js/Detector.js"></script>
	<script src="people/js/stats.min.js"></script>
	<script src="people/js/PathControls.js"></script>
	<script src="people/js/Tween.js"></script>
	<script src="people/js/RequestAnimationFrame.js"></script>
	
	
	
	<!-- 3d模型加载器 -->
	<script src="js/loaders/DDSLoader.js"></script>
	<script src="js/loaders/MTLLoader.js"></script>
	<script src="js/loaders/OBJLoader.js"></script>
	<script src="js/renderers/CSS2DRenderer.js"></script>

	<style>
		.label{
				color: #FFF;
				font-family: sans-serif;
				padding: 2px;
				background: rgba( 0, 0, 0, .6 );
		}
        body {
            background-color: #4682B4;
        }
	</style>
	

	<!-- ------------------------------------------------------------ -->

	<div id="ThreeJS" style="position: absolute; left: 0px; top: 0px"></div>

	<script>

            // 设置全局变量
            var scene, camera, renderer, controls,tween,door,mesh; 
            var keyboard = new THREEx.KeyboardState();//保持键盘的当前状态，可以随时查询
            var clock = new THREE.Clock();
        	var SCREEN_WIDTH = window.innerWidth-4, SCREEN_HEIGHT = window.innerHeight-4;
           //var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 20000;
        	var VIEW_ANGLE = 60, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 10000;
        	var materialArrayA = [];
        	var materialArrayB = [];
        	var matArrayA=[];//内墙
        	var matArrayB = [];//外墙
			var matArrayC = [];//红色的墙
        	var dummy= new THREE.Object3D();//仿制品
			var jgMeta = null;
            init();
            animate();
          
                  
   //1.场景         
   function initScene(){
	   scene = new THREE.Scene();
   }       
   
   //2.相机
   function initCamera(){
	   camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
	   camera.position.set(0,800,1000);
	   camera.lookAt(scene.position);	
	   camera.lookAt(0,0,0);	
	   scene.add(camera);
   }
   
   //3.渲染器
   function initRender(){
	   if ( Detector.webgl ){
			renderer = new THREE.WebGLRenderer( {antialias:true} );
	   }else{
			renderer = new THREE.CanvasRenderer(); 
		}
		   //设置渲染器的大小为窗口的内宽度，也就是内容区的宽度。
			renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
			container = document.getElementById( 'ThreeJS' );
			container.appendChild( renderer.domElement );
			renderer.setClearColor(0x4682B4,1.0);	
		 
		
		
		
   }
   
   //4.事件
   function initEvent(){
	   THREEx.WindowResize(renderer, camera);
	   THREEx.FullScreen.bindKey({ charCode : 'm'.charCodeAt(0) });
   }
   
   //5.控制
   function initControls(){
	   controls = new THREE.OrbitControls( camera, renderer.domElement );
   }
   
   //6.光源
   function initLight(){
	   // 位置不同，方向光作用于物体的面也不同，看到的物体各个面的颜色也不同	
	    // A start, 第二个参数是光源强度
	   	var directionalLight = new THREE.DirectionalLight( 0xffffff,1 );//模拟远处类似太阳的光源
	   	directionalLight.position.set( 0, 100, 0).normalize();
	   	scene.add( directionalLight );
	   	//A end
	   	var ambient = new THREE.AmbientLight( 0xffffff,1 ); //AmbientLight,影响整个场景的光源
	    ambient.position.set(0,0,0);
	    scene.add( ambient );	   	
	    //var pointlight = new THREE.PointLight(0x000000,1.5,2000);
		//scene.add(pointlight);	
   }
   
   //创建地板  
   function createFloor(){
	var loader=new THREE.TextureLoader();
	loader.load("images/floor.jpg",function(texture){
		texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
		texture.repeat.set( 10, 10 );
		var floorGeometry = new THREE.BoxGeometry(1600, 1100, 1);
		var floorMaterial = new THREE.MeshBasicMaterial( { map: texture, side: THREE.DoubleSide } );
		var floor = new THREE.Mesh(floorGeometry, floorMaterial);
	   	floor.position.y = -0.5;
	   	floor.rotation.x = Math.PI / 2;
	    scene.add(floor);	
	});
	
    //茶色：0x58ACFA   透明玻璃色：0XECF1F3
    var glass_material=new THREE.MeshBasicMaterial( { color: 0XECF1F3});
    glass_material.opacity=0.4;
    glass_material.transparent=true;
    
   	 var  left_wall=returnWallObject(20, 200, 1100,0,matArrayB,-801,100,0);
   	 var  left_cube=returnWallObject(20, 110, 1100,0,matArrayB,-801,100,0);	
   	 createResultBsp(left_wall,left_cube,1);
    createCubeWall(1, 110, 1100,0,glass_material,-801,100,0);
  
    var  right_wall=returnWallObject(20, 200, 1100,1,matArrayB,801,100,0);
  	var  right_cube=returnWallObject(20, 110, 1100,0,matArrayB,801,100,0);	
  	createResultBsp(right_wall,right_cube,1);	
  	createCubeWall(1, 110, 1100,0,glass_material,801,100,0);    
   }
   
   //墙上挖门，通过两个几何体生成BSP对象
   function createResultBsp(bsp,less_bsp,mat){	   
	   switch(mat)
	    {
	        case 1:
	        	var material = new THREE.MeshPhongMaterial({color:0x9cb2d1,specular:0x9cb2d1,shininess:30,transparent:true,opacity:1});
	            break;
	        case 2:
	            var material = new THREE.MeshPhongMaterial({color:0xafc0ca,specular:0xafc0ca,shininess:30,transparent:true,opacity:1});
	            break;
	        default:
	    }
	    
	    var sphere1BSP = new ThreeBSP(bsp);  
	    var cube2BSP = new ThreeBSP(less_bsp);//0x9cb2d1 淡紫,0xC3C3C3 白灰 , 0xafc0ca灰
	    var resultBSP = sphere1BSP.subtract(cube2BSP);  	      
	    var result = resultBSP.toMesh(material); 
	    result.material.flatshading = THREE.FlatShading;  
	    result.geometry.computeFaceNormals();  //重新计算几何体侧面法向量
	    result.geometry.computeVertexNormals();  
	    result.material.needsUpdate = true;  //更新纹理
	    result.geometry.buffersNeedUpdate = true;  
	    result.geometry.uvsNeedUpdate = true;  
	    scene.add(result);     
   }
   
   //创建墙，墙体就是一个立方体，注意这里 宽 高 和深度 是相对于摄像头的视角。
   function createCubeWall(width, height, depth,angle,material,x,y,z){
   	var cubeGeometry = new THREE.BoxGeometry(width, height, depth );     
       var cube = new THREE.Mesh( cubeGeometry, material );  
       cube.position.x = x;  
       cube.position.y = y;  
       cube.position.z = z;  
       cube.rotation.y += angle*Math.PI;  //-逆时针旋转,+顺时针
       scene.add(cube);  
   }

   //返回墙对象
   function returnWallObject(width, height, depth,angle,material,x,y,z){
   	var cubeGeometry = new THREE.BoxGeometry(width, height, depth);     
       var cube = new THREE.Mesh( cubeGeometry, material );  
       cube.position.x = x;  
       cube.position.y = y;  
       cube.position.z = z;  
       cube.rotation.y += angle*Math.PI;    
       return cube;
   }

   //创建墙纹理
  function createWallMaterail(){
	   matArrayA.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //前  0xafc0ca :灰色
	   matArrayA.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //后  
	   matArrayA.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //上  0xd6e4ec： 偏白色
	   matArrayA.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //下  
	   matArrayA.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //左    0xafc0ca :灰色
	   matArrayA.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //右
	      
	   matArrayB.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //前  0xafc0ca :灰色
	   matArrayB.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //后  0x9cb2d1：淡紫
	   matArrayB.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //上  0xd6e4ec： 偏白色
	   matArrayB.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //下  
	   matArrayB.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //左   0xafc0ca :灰色
	   matArrayB.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //右
	   
	   
	   matArrayC.push(new THREE.MeshPhongMaterial({color: 0xFFC0CB}));  //前  0xafc0ca :灰色
	   matArrayC.push(new THREE.MeshPhongMaterial({color: 0x9cb2d1}));  //后  0x9cb2d1：淡紫
	   matArrayC.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //上  0xd6e4ec： 偏白色
	   matArrayC.push(new THREE.MeshPhongMaterial({color: 0xd6e4ec}));  //下  
	   matArrayC.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //左   0xafc0ca :灰色
	   matArrayC.push(new THREE.MeshPhongMaterial({color: 0xafc0ca}));  //右
	     	   
   }
   
   //创建房间布局
   function createLayout(){ 
        
       // 墙面1 立方体比较长的面  左一
       createCubeWall(10, 200, 900,0,matArrayB,-651,100,0);  
       // 墙面2  立方体比较长的面   右一
       createCubeWall(10, 200, 900,1,matArrayB,651,100,0);
       // 墙面3 门对面的墙 立方体比较短的面  
       createCubeWall(10, 200, 1310,1.5,matArrayB,0,100,-451); 
       
       // 墙面4   带门的面  
       var wall=returnWallObject(1310, 200,10,0,matArrayB,0,100,455); 
       // 门框 
       var door_cube=returnWallObject(100, 180,10,0,matArrayB,0,90,455);
      createResultBsp(wall,door_cube,1);
      
    
       //为墙面安装门,右门
     var loader=new THREE.TextureLoader();
	 loader.load("images/door_right.png",function(texture){
		var  doorgeometry = new THREE.BoxGeometry(100, 180, 2);
		 var doormaterial = new THREE.MeshBasicMaterial({map:texture,color:0xffffff});
	         doormaterial.opacity=1.0;
	         doormaterial.transparent=true;
	         door = new THREE.Mesh( doorgeometry,doormaterial);	       	     	
	         door.position.set(-50,0,0);	         
	        var door1=door.clone();
	        door1.position.set(50,0,0);
	        door1.visible=false;
	        dummy.add(door);	         	 	      	      	        
	        dummy.add(door1);	        
	        dummy.position.set(50,90,451)
	        scene.add(dummy);
	});
            
       // 房间A:隔墙1 
       //createCubeWall(10, 200, 250,0,matArrayC,-151,100,325); 
	   
       
      //厕所
      //var cube=returnWallObject(10, 200, 260,0.5,matArrayA, 125,100,-250);  
      //厕所门框
      // var door_cube1 =returnWallObject(10, 160,80,0.5,matArrayA,155,90, -250); 
      // createResultBsp(cube,door_cube1,2);
       
        
   }
    
	//创建机柜	
	function createJG(x,z,title){
		var jgHeight = 200;
	   //创建机柜
	   var geometry = new THREE.CubeGeometry( 70, jgHeight, 80);	  
	   var side1 = [new THREE.Vector2(0.2, 0.07), new THREE.Vector2(1, 0.07), new THREE.Vector2(1, .333), new THREE.Vector2(0.2, .333)];
	   var side2 = [new THREE.Vector2(0, .333), new THREE.Vector2(1, .333), new THREE.Vector2(1, .666), new THREE.Vector2(0, .666)];
	   var top = [new THREE.Vector2(0, .666), new THREE.Vector2(.5, .666), new THREE.Vector2(.5, 1), new THREE.Vector2(0, 1)];
	   var bottom = [new THREE.Vector2(0.5, .666), new THREE.Vector2(1, .666), new THREE.Vector2(1, 1), new THREE.Vector2(0.5, 1)]; 	
  
		geometry.faceVertexUvs[0] = [];
		geometry.faceVertexUvs[0][0] = [ side1[0], side1[1], side1[3]];
		geometry.faceVertexUvs[0][1] = [ side1[1], side1[2], side1[3]];
		  
		geometry.faceVertexUvs[0][2] = [ side2[0], side2[1], side2[3]];
		geometry.faceVertexUvs[0][3] = [ side2[1], side2[2], side2[3]];
		  
		geometry.faceVertexUvs[0][4] = [ top[0], top[1], top[3] ];
		geometry.faceVertexUvs[0][5] = [ top[1], top[2], top[3] ];
		  
		geometry.faceVertexUvs[0][6] = [ side2[0], side2[1], side2[3] ];
		geometry.faceVertexUvs[0][7] = [ side2[1], side2[2], side2[3] ];
		  
		geometry.faceVertexUvs[0][8] = [ bottom[0], bottom[1], bottom[3] ];
		geometry.faceVertexUvs[0][9] = [ bottom[1], bottom[2], bottom[3] ];
		  
		geometry.faceVertexUvs[0][10] = [ top[0], top[1], top[3] ];
		geometry.faceVertexUvs[0][11] = [ top[1], top[2], top[3] ];
  
	   mesh = new THREE.Mesh(geometry,  jgMeta);	   
	   mesh.position.x = x;
	   mesh.position.z = z;
	   mesh.position.y = jgHeight/2;
	   mesh.rotation.y = 1.5*Math.PI;

	   
	   //创建标签网格
	   //var g = new THREE.PlaneGeometry( 64, 64);
	   var g = new THREE.BoxGeometry(64, 1, 64 );     
	   var m  = new THREE.MeshPhongMaterial( { map: new THREE.CanvasTexture(getTextCanvas(title))} );
	   m.transparent=true;	   
	   var plane = new THREE.Mesh( g,m );
	   plane.position.y = jgHeight/2;
	   plane.position.x = 0;
	   plane.position.z = 0;
	  // plane.rotation.x = 1.5*Math.PI;;
	   plane.rotation.y = 0.5*Math.PI;;
	  
	  
	  
	   
	   
	  
	   mesh.add(plane);
	  
	  scene.add( mesh );	   			
	}
	 
	 
	 
	 function getTextCanvas(text){ 
		 var width=64, height=64; 
		 var canvas = document.createElement('canvas');
		 canvas.width = width;
		 canvas.height = height;
		 var ctx = canvas.getContext('2d'); 
		 ctx.font = 16+'px " bold'; 
		 ctx.fillStyle = '#ddd';
		 ctx.textAlign = 'center';
		 ctx.textBaseline = 'middle';
		 ctx.fillText(text, width/2,height/2); 
		 return canvas;
  }
	 
	 
   //7.初始化OBJ对象
   function initObject(){
	   //墙纹理
	   createWallMaterail();
	   createFloor();
	   createLayout();
	   
	   //机柜材料	   
	   jgMeta = new THREE.MeshPhongMaterial( { map: THREE.ImageUtils.loadTexture('images/jg.png')});
	   
	   //机柜
	   index = 0;
	   for(var i=0;i<=4;i++){
		createJG(200*i-500,-100,'资A'+(++index));
	    createJG(200*i-500,0,'资A'+(++index));
	    createJG(200*i-500,100,'资A'+(++index));
	    createJG(200*i-500,200,'资A'+(++index));
	    createJG(200*i-500,300,'资A'+(++index));
	   }
   }
   
   
   
//初始化函数 		
function init() 
{
	initScene();
	initCamera();
	initRender();
	initEvent();
	initControls();
	initLight();
	initObject();	
	
	//显示坐标系
	//var axes = new THREE.AxisHelper(400);
	//scene.add(axes);
	
   // var helper = new THREE.GridHelper( 1000, 50 ,0x6A5ACD, 0x6A5ACD);
   // scene.add( helper );

   //加载3d模型
   THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
  var mtlLoader = new THREE.MTLLoader();
  //设置路径，也可不是设置，在load中加载完整路径也可  
    mtlLoader
	.setPath( 'obj/flower/' )
	.load( 'file.mtl', 
			// 资源加载成功后执行的函数 
             //@params materials THREE.MTLLoader.MaterialCreator
                   function( materials ) {				   
						materials.preload();
						console.log(materials)
						var objLoader = new THREE.OBJLoader();
						objLoader.setMaterials( materials );		
						objLoader.setPath('obj/flower/' );
						objLoader.load( 'file.obj', function ( object ) {							
							object.position.y =0;
							object.position.z =480
							
							for(var i=0;i<10;i++){
								var obj2 = object.clone();
							    obj2.position.x = -400+100*i;
								scene.add( obj2 );
							}
						});
						
						
				});



	//添加灭火器
	 var mtlLoader2 = new THREE.MTLLoader();
    //设置路径，也可不是设置，在load中加载完整路径也可  
    mtlLoader2
	.setPath( 'obj/fire/' )
	.load( 'fire.mtl', 
			// 资源加载成功后执行的函数              
                   function( materials ) {				   
						materials.preload();
						var objLoader = new THREE.OBJLoader();
						objLoader.setMaterials( materials );		
						objLoader.setPath('obj/fire/' );
						objLoader.load( 'fire.obj', function ( object ) {							
							object.position.y =0;							
							object.scale.addScalar(-0.7);
							
							var temp = object.clone();
							temp.position.z = -400
							temp.position.x = 600;
							scene.add(temp);
							
							temp = object.clone();
							temp.position.z = -400
							temp.position.x = 570;
							scene.add(temp);
							
							var temp = object.clone();
							temp.position.z = -400
							temp.position.x = -600;
							scene.add(temp);
							
							temp = object.clone();
							temp.position.z = -400
							temp.position.x = -570;
							scene.add(temp);						
							
						});
						
						
				});

				
	//监听键盘按键
   document.addEventListener("keydown",onkeyDown,false);
}

 

var door_state=true;//默认是门是关闭的
//Enter=13,Space=32;
function onkeyDown(event) {
    switch(event.keyCode) {
    case 13:
    	console.log(event.keyCode);
         if(door_state){
        	 dummy.rotation.y+=0.5*Math.PI;
             door_state=false;
         }else{      		
        	dummy.rotation.y-=0.5*Math.PI;
             door_state=true;
         }
        break;       	
        default:
          console.log(event.keyCode);
          break;
    }
}


function animate() 
{   
    requestAnimationFrame( animate );
    renderer.render( scene, camera );
    TWEEN.update(  );
	update();
}

function update()
{
	var delta = clock.getDelta(); 
	var moveDistance = 200 * delta; 
	var rotateAngle = Math.PI / 2 * delta;
	controls.update();
}


</script>
</body>
</html>
